package ar.camera.globject;


import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Arrays;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.opengl.GLUtils;
import ar.activity.R;
import ar.camera.pojo.GLLocation;
import ar.camera.pojo.GLPoint;
import ar.utils.GLIconUtils;

public class LocationIcon {

	private float textScale = 2.5f;
	private String textInfo;
	private Point textInfoPosition;
	private GLLocation glLocation;
	private boolean isLoadedTexture;
	private float delta = 0.35f;

	private FloatBuffer vertexBuffer;
	private float vertices[];
	private float originalVertices[];

	private FloatBuffer textureBuffer;
	private float texture[] = {
			// Mapping coordinates for the vertices
			0.0f, 1.0f, // top left (V2)
			0.0f, 0.0f, // bottom left (V1)
			1.0f, 1.0f, // top right (V4)
			1.0f, 0.0f // bottom right (V3)
	};

	private int[] textures = new int[1];

	public LocationIcon(GLLocation glLct) {
		glLocation = glLct;
		vertices = new float[12];

		vertices[0] = (float) (glLct.x - delta); // 1
		vertices[1] = glLct.y - 0.1f;
		vertices[2] = (float) (glLct.z);

		vertices[3] = (float) (glLct.x - delta);// 2
		vertices[4] = glLct.y + 0.7f;
		vertices[5] = (float) (glLct.z);

		vertices[6] = (float) (glLct.x + delta);// 4
		vertices[7] = glLct.y - 0.1f;
		vertices[8] = (float) (glLct.z);

		vertices[9] = (float) (glLct.x + delta);// 3
		vertices[10] = glLct.y + 0.7f;
		vertices[11] = (float) (glLct.z);

		originalVertices = new float[12];
		originalVertices = Arrays.copyOf(vertices, vertices.length);

		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
		byteBuffer.order(ByteOrder.nativeOrder());
		vertexBuffer = byteBuffer.asFloatBuffer();
		vertexBuffer.put(vertices);
		vertexBuffer.position(0);

		byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
		byteBuffer.order(ByteOrder.nativeOrder());
		textureBuffer = byteBuffer.asFloatBuffer();
		textureBuffer.put(texture);
		textureBuffer.position(0);

		textInfoPosition = new Point(15, 230);
		isLoadedTexture = false;
		this.textInfo = glLct.textInfo;
	}

	/**
	 * 
	 * @param gl
	 * @param context
	 * @param isCurrLct
	 *            is the user current location.
	 */
	public void loadGLTexture(GL10 gl, Context context, boolean isCurrLct) {

		InputStream is = context.getResources().openRawResource(
				R.drawable.location_icon);
		if (isCurrLct) {
			is = context.getResources().openRawResource(
					R.drawable.location_icon_current);
		}
		Bitmap bitmap;
		try {
			bitmap = BitmapFactory.decodeStream(is);
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				// Ignore.
			}
		}

		Bitmap bmOverlay = Bitmap.createBitmap(bitmap.getWidth(),
				bitmap.getHeight(), bitmap.getConfig());
		Canvas canvas = new Canvas(bmOverlay);
		
		Paint paint = new Paint();
		paint.setColor(Color.WHITE);
		paint.setTextSize(14 * textScale);
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);		
		canvas.drawBitmap(bitmap, 0, 0, paint);
		canvas.drawText(textInfo, textInfoPosition.x, textInfoPosition.y, paint);

		gl.glGenTextures(1, textures, 0);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
				GL10.GL_NEAREST);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
				GL10.GL_LINEAR);

		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmOverlay, 0);
		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		gl.glEnable(GL10.GL_BLEND);

		bitmap.recycle();
		isLoadedTexture = true;
	}

	public void draw(GL10 gl) {
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
		byteBuffer.order(ByteOrder.nativeOrder());
		vertexBuffer = byteBuffer.asFloatBuffer();
		vertexBuffer.put(vertices);
		vertexBuffer.position(0);

		gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		gl.glFrontFace(GL10.GL_CW);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);

		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	}

	public GLLocation getGlLocation() {
		return glLocation;
	}

	public void setGlLocation(GLLocation glLocation) {
		this.glLocation = glLocation;
	}

	public boolean isLoadedTexture() {
		return isLoadedTexture;
	}

	public void setTextInfo(String textInfo) {
		this.textInfo = textInfo;
	}

	public float[] getVertices() {
		return vertices;
	}

	/**
	 * 
	 * @param azimut
	 *            in degrees
	 * 
	 */
	public void updateVertices(float azimut) {

		azimut = (float) (azimut * Math.PI / 180);

		vertices = Arrays.copyOf(originalVertices, originalVertices.length);
		for (int i = 0; i <= 9; i += 3) {
			GLPoint p = new GLPoint(vertices[i], vertices[i + 1],
					vertices[i + 2]);
			GLPoint center = new GLPoint(glLocation.x, glLocation.y,
					glLocation.z);
			p = GLIconUtils.rotateY(p, center, azimut);
			vertices[i] = p.x;
			vertices[i + 1] = p.y;
			vertices[i + 2] = p.z;
		}

	}
}
